#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Syslog测试脚本
用于向syslog服务器发送测试消息
"""

import socket
import time
import random
from datetime import datetime

def send_syslog_message(host='localhost', port=5140, message='', facility=16, severity=6):
    """
    发送syslog消息
    
    Args:
        host: syslog服务器地址
        port: syslog服务器端口
        message: 消息内容
        facility: 设施代码 (16=local0)
        severity: 严重级别 (0=emergency, 1=alert, 2=critical, 3=error, 4=warning, 5=notice, 6=info, 7=debug)
    """
    try:
        # 计算优先级
        priority = facility * 8 + severity
        
        # 格式化syslog消息
        timestamp = datetime.now().strftime('%b %d %H:%M:%S')
        hostname = 'testhost'
        tag = 'testtag'
        
        syslog_message = f"<{priority}>{timestamp} {hostname} {tag}: {message}"
        
        # 发送UDP消息
        sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        sock.sendto(syslog_message.encode('utf-8'), (host, port))
        sock.close()
        
        print(f"[{datetime.now().strftime('%H:%M:%S')}] 发送消息: {message}")
        return True
        
    except Exception as e:
        print(f"发送失败: {str(e)}")
        return False

def test_normal_messages(host='localhost', port=5140, count=5):
    """
    发送正常测试消息
    """
    print(f"\n=== 发送 {count} 条正常消息 ===")
    
    normal_messages = [
        "System startup completed successfully",
        "User login: admin from 192.168.1.100",
        "Database connection established",
        "Backup process started",
        "Configuration file loaded",
        "Service health check passed",
        "Network interface eth0 is up",
        "Disk usage: 45% of /var/log",
        "Memory usage: 2.1GB/8GB",
        "CPU temperature: 45°C"
    ]
    
    for i in range(count):
        message = random.choice(normal_messages)
        send_syslog_message(host, port, message, facility=16, severity=6)  # info级别
        time.sleep(0.5)

def test_alert_messages(host='localhost', port=5140, count=3):
    """
    发送告警测试消息（包含关键词）
    """
    print(f"\n=== 发送 {count} 条告警消息 ===")
    
    alert_messages = [
        "Database connection error: timeout after 30 seconds",
        "Critical system failure: disk space full on /var",
        "Security alert: multiple failed login attempts detected",
        "Emergency: service crashed with exception",
        "Error: unable to connect to external API",
        "Critical: memory usage exceeded 95%",
        "Alert: suspicious network activity detected",
        "System error: configuration file corrupted",
        "Emergency shutdown: temperature critical",
        "Fatal error: database corruption detected"
    ]
    
    for i in range(count):
        message = random.choice(alert_messages)
        severity = random.choice([0, 1, 2, 3])  # emergency, alert, critical, error
        send_syslog_message(host, port, message, facility=16, severity=severity)
        time.sleep(1)

def test_continuous_messages(host='localhost', port=5140, duration=30):
    """
    持续发送消息（用于压力测试）
    """
    print(f"\n=== 持续发送消息 {duration} 秒 ===")
    
    start_time = time.time()
    count = 0
    
    messages = [
        "Application heartbeat",
        "Process monitoring check",
        "Network connectivity test",
        "Service status update",
        "Performance metrics collected"
    ]
    
    while time.time() - start_time < duration:
        message = f"{random.choice(messages)} #{count+1}"
        send_syslog_message(host, port, message, facility=16, severity=6)
        count += 1
        time.sleep(0.1)
    
    print(f"共发送 {count} 条消息")

def main():
    print("Syslog测试脚本")
    print("=" * 50)
    
    # 配置
    host = input("请输入syslog服务器地址 (默认: localhost): ").strip() or 'localhost'
    port_input = input("请输入syslog服务器端口 (默认: 5140): ").strip()
    port = int(port_input) if port_input else 5140
    
    print(f"\n目标服务器: {host}:{port}")
    
    while True:
        print("\n请选择测试类型:")
        print("1. 发送正常消息")
        print("2. 发送告警消息（包含关键词）")
        print("3. 持续发送消息（压力测试）")
        print("4. 发送自定义消息")
        print("5. 综合测试")
        print("0. 退出")
        
        choice = input("\n请输入选择 (0-5): ").strip()
        
        if choice == '0':
            print("退出测试")
            break
        elif choice == '1':
            count = int(input("请输入消息数量 (默认: 5): ").strip() or '5')
            test_normal_messages(host, port, count)
        elif choice == '2':
            count = int(input("请输入消息数量 (默认: 3): ").strip() or '3')
            test_alert_messages(host, port, count)
        elif choice == '3':
            duration = int(input("请输入持续时间(秒) (默认: 30): ").strip() or '30')
            test_continuous_messages(host, port, duration)
        elif choice == '4':
            message = input("请输入自定义消息: ").strip()
            if message:
                severity = int(input("请输入严重级别 (0-7, 默认: 6): ").strip() or '6')
                send_syslog_message(host, port, message, facility=16, severity=severity)
        elif choice == '5':
            print("\n=== 开始综合测试 ===")
            test_normal_messages(host, port, 3)
            time.sleep(2)
            test_alert_messages(host, port, 2)
            print("\n综合测试完成")
        else:
            print("无效选择，请重新输入")

if __name__ == '__main__':
    main()